import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

pd.set_option('display.max_columns', None)
plt.figure(figsize=[12, 6])
spr = 1
spc = 2
spn = 0

# 1.
# 使用train.csv数据，完成以下操作
df = pd.read_csv(r'..\..\..\large_data\ML2\train.csv')

# (1)
# 使用datetime列，切分月，日，时数据
# ①    使用映射，切分月
df['month'] = df['datetime'].map(lambda x: int(x.split(' ')[0].split('-')[1]))

# ②    使用映射，切分日
df['day'] = df['datetime'].map(lambda x: int(x.split(' ')[0].split('-')[2]))

# ③    使用映射，切分时
df['hour'] = df['datetime'].map(lambda x: int(x.split(' ')[1].split(':')[0]))

# (2)
# 绘制小时与用车辆关系图
# ①    使用分组函数统计用车辆
hour_count = df.groupby('hour').agg(np.sum)['count']
# ②    可视化处理
spn += 1
ax = plt.subplot(spr, spc, spn)
ax.set_title('hour - count')
hour_count.plot(kind='line', ax=ax)


#
# (3)
# 创建一列新的数据，将7时到10时，设定为早高峰，10
# 时到17时，设定为夜晚低谷，将17时到22时设定为晚高峰，其他时间设定为晚上低谷
# ①    创建自定义函数
def hour_section(h):
    if 7 < h <= 10:
        return 1  # 早高峰
    elif 10 < h <= 17:
        return 2  # 夜晚低谷
    elif 17 < h <= 22:
        return 3  # 晚高峰
    else:
        return 0  # 晚上低谷


# ②    使用映射创建新的一列数据，并按照要求调整数据
df['hour_section'] = df['hour'].map(hour_section)

# 2.
# 使用和上题相同数据，完成噪音内容处理
# (1)
# 绘制count的箱线图
# ①    导入对应库
import seaborn as sns

# ②    使用合理方式可视化
spn += 1
ax = plt.subplot(spr, spc, spn)
ax.set_title('count')
sns.boxplot(data=df, y='count', ax=ax)

#
# (2)
# 打印输出噪音个数
# ①    正确编写噪音查找公式
mu = df['count'].mean()
sigma = df['count'].std()
# idx_good = df['count'].between(mu - 3 * sigma, mu + 3 * sigma)
idx_good = (df['count'] >= mu - 3 * sigma) & (df['count'] <= mu + 3 * sigma)  # ATTENTION &
idx_noise = np.invert(idx_good)

# ②    计算个数
print(f'噪音个数: {sum(idx_noise)}')

# (3)
# 保留非噪音数据（去除噪音）
# ①    正确使用公式
# ②    将满足非噪音部分数据保留
xlen1 = len(df)
df.drop(labels=df.index[idx_noise], axis=0, inplace=True)
xlen2 = len(df)
print(f'去除噪音:{xlen1-xlen2}个')
